package com.sh.data.engine.common.util;

import com.sh.data.engine.common.constants.Constants;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.NotImplementedException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;

/**
 * @author: mengzheng.mhc
 * @date: 2024/6/11 10:36
 */
public class ServletUtils {

    public static String getRemoteIp() {
        return getRequest().getRemoteAddr();
    }

    public static String getRemoteUA() {
        return getRequest().getHeader("User-Agent");
    }

    public static String getReferer() {
        return getRequest().getHeader("Referer");
    }

    /**
     * 返回当前应用的basePath,形式如 http://localhost:8080/MyApp/
     *
     * @return
     */
    public static String getBasePath() {
        HttpServletRequest request = getRequest();
        return request.getScheme()
            + "://"
            + request.getServerName()
            + ":"
            + request.getServerPort()
            + request.getContextPath()
            + "/";
    }

    public static String getCurrentUri() {
        HttpServletRequest request = getRequest();
        return request.getScheme()
            + "://"
            + request.getServerName()
            + ":"
            + request.getServerPort()
            + request.getContextPath()
            + request.getRequestURI();
    }

    public static String getQueryString(String... excludes) {
        Set<String> excludeSet = new HashSet<>();
        if (ArrayUtils.isNotEmpty(excludes)) {
            Arrays.asList(excludes).stream()
                .filter(Objects::nonNull)
                .forEach(exclude -> excludeSet.add(exclude));
        }

        HttpServletRequest request = getRequest();
        StringBuilder sb = new StringBuilder();
        request.getParameterMap().entrySet().stream()
            .forEach(
                entry -> {
                    String key = entry.getKey();
                    String[] values = entry.getValue();
                    if (excludeSet.contains(key)) {
                        return;
                    }
                    if (values == null || values.length == 0) {
                        return;
                    }

                    for (String value : values) {
                        sb.append(key);
                        sb.append("=");
                        sb.append(value);
                        sb.append("&");
                    }
                });

        String uri = sb.toString();

        if (uri.length() == 0) {
            return StringUtils.EMPTY;
        }

        if (uri.endsWith("&") && uri.length() > 0) {
            return uri.substring(0, uri.length() - 1);
        }

        return uri;
    }

    @SuppressWarnings("unchecked")
    public static <T> T getRequestAttribute(String key) {
        return (T) getRequest().getAttribute(key);
    }

    public static void setRequestAttribute(String key, Object value) {
        getRequest().setAttribute(key, value);
    }

    public static HttpServletRequest getRequest() {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        if (requestAttributes == null) {
            return null;
        }

        return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    }

    public static HttpServletResponse getResponse() {
        return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
    }

    @SuppressWarnings("unchecked")
    public static <T> T getSessionAttribute(String key) {
        return (T) getSession().getAttribute(key);
    }

    public static void setSessionAttribute(String key, Object value) {
        getSession().setAttribute(key, value);
    }

    public static void sessionInvalidate() {
        getSession().invalidate();
    }

    public static HttpSession getSession() {
        return getRequest().getSession();
    }

    public static Long getProjectId() {
        return getProjectId(true);
    }

    /**
     * 获取项目ID
     *
     * @return
     */
    public static Long getProjectId(boolean throwsException) {
        String projectId = getRequest().getHeader(Constants.HEADER_PROJECT_ID);

        if (StringUtils.isBlank(projectId) || "null".equals(projectId)) {
            projectId = getRequest().getParameter(Constants.PARAM_PROJECT_ID);
        }
        if (StringUtils.isBlank(projectId) || "null".equals(projectId)) {
            projectId = String.valueOf(getRequest().getAttribute(Constants.PARAM_PROJECT_ID));
        }
        if (StringUtils.isBlank(projectId) && throwsException) {
            throw new IllegalArgumentException("请求header中缺失" + Constants.HEADER_PROJECT_ID);
        }
        if (StringUtils.isBlank(projectId) || "null".equals(projectId)) {
            return null;
        }
        return Long.valueOf(projectId);
    }

    /**
     * TODO: 获取用户id
     *
     * @return
     */
    public static String getUserId() {
        String userId = getRequest().getHeader(Constants.HEADER_USER_ID);

        if (StringUtils.isBlank(userId)) {
            userId = getRequest().getParameter(Constants.PARAM_USER_ID);
        }
        if (StringUtils.isBlank(userId)) {
            userId = String.valueOf(getRequest().getAttribute(Constants.PARAM_USER_ID));
        }
        if (StringUtils.isBlank(userId)) {
            throw new IllegalArgumentException("请求header中缺失" + Constants.HEADER_USER_ID);
        }
        return userId;
    }

    /**
     * TODO: 获取第三方标识
     *
     * @param throwsException
     * @return
     */
    public static String getThirdFlag(boolean throwsException) {
        throw new NotImplementedException();
//        String thirdFlag = getRequest().getHeader(Constants.HEADER_THIRD_FLAG);
//
//        if (StringUtils.isBlank(thirdFlag)) {
//            thirdFlag = getRequest().getParameter(Constants.PARAM_THIRD_FLAG);
//        }
//        if (StringUtils.isBlank(thirdFlag)) {
//            thirdFlag = String.valueOf(getRequest().getAttribute(Constants.PARAM_THIRD_FLAG));
//        }
//        if (StringUtils.isBlank(thirdFlag) && throwsException) {
//            throw new IllegalArgumentException("请求header中缺失" + Constants.HEADER_THIRD_FLAG);
//        }
//        return thirdFlag;
    }

    /**
     * 得到请求的ip,能够应对代理
     */
    public static String getIpAddress(HttpServletRequest request) {
        String unknown = "unknown";

        String ip = request.getHeader("X-Forwarded-For");

        if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }

        if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }

        if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }

        if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }

        if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
        }

        if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }

        // 对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
        if (ip != null && ip.length() > 0) {
            String[] ips = ip.split(",");
            if (ips.length > 0) {
                ip = ips[0];
            }
        }

        return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
    }
}
